#pragma once

namespace AppSecInc
{
	namespace Databases
	{
		namespace ODBC
		{
		    //! An ODBC error
			typedef struct
			{
				std::wstring state;
				std::wstring message;
				int native_error;
			} ODBCError;

		    //! A diagnostics message, see http://msdn.microsoft.com/en-us/library/ms713606(VS.85).aspx
			typedef struct
			{
				//! Identifies the vendor of the component in which the error or warning occurred or that received the error or warning directly from the data source.
				std::wstring vendor;
				//! Identifies the component in which the error or warning occurred or that received the error or warning directly from the data source.
				std::wstring component;
				//! Identifies the data source. For file-based drivers, this is typically a file format, such as Xbase[1] For DBMS-based drivers, this is the DBMS product.
				std::wstring datasource;
				//! Generated by the ODBC component.
				std::wstring text;
			} ODBCDiagnosticsMessage;

		    //! An ODBC handle (smart pointer), bound to a connection
			class ODBCHandle
			{
			protected:
                //! type of handle
                SQLSMALLINT _type;
                //! ODBC handle
                SQLHANDLE _handle;
                //! ODBC connection handle
                SQLHANDLE _hconn;
            private:
                void operator=(const ODBCHandle&);
			public:
                //! returns the ODBC handle
                inline SQLHANDLE Peek() const { return _handle; }
                //! returns the connection handle
				inline SQLHANDLE PeekConnection() const { return _hconn; }
				ODBCHandle();
				virtual ~ODBCHandle();
                //! allocates a handle, fails if a handle has been previously allocated
				void Allocate(SQLSMALLINT type, SQLHANDLE hconn);
                //! releases the previously allocated handle, fails if no handle has been allocated
                void Release();
                //! get the text representation of the errors on an ODBC handle
                static std::wstring GetError(SQLHANDLE handle, int type);
                //! get an array of errors on an ODBC handle
				static std::vector<ODBCError> GetErrors(SQLHANDLE handle, int type);
				//! get an array of diag fields or messages
				//! for a list of diag identifiers see http://msdn.microsoft.com/en-us/library/ms710181(VS.85).aspx
				static std::vector<std::wstring> GetDiagFields(SQLHANDLE handle, int type, int diagidentifier);
				//! get diagnostics messages (cleaned up SQL_DIAG_MESSAGE_TEXT)
				static std::vector<ODBCDiagnosticsMessage> GetDiagMessages(SQLHANDLE handle, int type);
                //! get the text representation of the errors on an ODBC handle
                std::wstring GetError() const { return GetError(_handle, _type); }
                //! get an array of errors on the current ODBC handle
				std::vector<ODBCError> GetErrors() const { return GetErrors(_handle, _type); }
                //! get an array of messages on the current ODBC handle
				std::vector<std::wstring> GetDiagFields(int diagidentifier) const { return GetDiagFields(_handle, _type, diagidentifier); }
                //! get an array of text messages on the current ODBC handle (cleaned up SQL_DIAG_MESSAGE_TEXT)
				std::vector<ODBCDiagnosticsMessage> GetDiagMessages() const { return GetDiagMessages(_handle, _type); }
			};
		}
	}
}





